package com.itheima.health.service.impl;

import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.entity.HotSetmeal;
import com.itheima.health.service.ReportService;
import com.itheima.health.vo.GetBusinessReportDataParam;
import com.itheima.health.vo.MemberReportVO;
import com.itheima.health.vo.SetmealCountVO;
import com.itheima.health.vo.SetmealReportExcelVO;
import com.qiniu.util.StringUtils;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 数据报表service
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;


    @Override
    /**
     * 运营数据统计
     */
    public GetBusinessReportDataParam statis() {
        //会员数据统计
        GetBusinessReportDataParam getBusinessReportDataParam = new GetBusinessReportDataParam();
        //存储当日时间
//        当日新增会员数
        LocalDate date = LocalDate.now();
//        转换成字符串
        String now = date.toString();
//        获取时间最大值最小值

//          得到时间
        Integer Todays = memberDao.Today(date,date);
//        全部会员数
        Integer alls = memberDao.all();
//        本周新增会员数
        LocalDate begin = date.with(DayOfWeek.MONDAY);
        LocalDate end = date.with(DayOfWeek.SUNDAY);
//        查询
        Integer Week = memberDao.week(begin,end);
//        本月新增会员
        LocalDate monthbegin = date.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate monthend = date.with(TemporalAdjusters.lastDayOfMonth());
//        查询
        Integer Month = memberDao.week(monthbegin,monthend);


//        预约到诊数据统计
//        今日预约查询
        Integer bookingTodays = orderDao.bookingToday(date,date);
//        本周预约查询
        LocalDate bookingWeekbegin = date.with(DayOfWeek.MONDAY);
        LocalDate bookingWeekend = date.with(DayOfWeek.SUNDAY);
        Integer bookingWeek = orderDao.bookingToday(bookingWeekbegin,bookingWeekend);
//        本月预约查询
        LocalDate bookingmonthbegin = date.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate bookingmonthend = date.with(TemporalAdjusters.lastDayOfMonth());
        Integer bookingMonth = orderDao.bookingToday(bookingmonthbegin,bookingmonthend);


//        今日到诊查询
        String visits = "已到诊";
        Integer VisitsTodays = orderDao.visitsTodays(date,date,visits);
//        本周到诊人数
        LocalDate VisitsWeekbegin = date.with(DayOfWeek.MONDAY);
        LocalDate VisitsWeekend = date.with(DayOfWeek.SUNDAY);
        Integer VisitsWeek = orderDao.visitsTodays(VisitsWeekbegin,VisitsWeekend,visits);
//        本月到诊人数
        LocalDate Visitsmonthbegin = date.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate Visitsmonthend = date.with(TemporalAdjusters.lastDayOfMonth());
        Integer VisitsMonthend = orderDao.visitsTodays(Visitsmonthbegin,Visitsmonthend,visits);

//        热门套餐
//        套餐名称
        List<HotSetmeal> hotSetmealList = orderDao.Popularpackages();



        getBusinessReportDataParam.setHotSetmeal(hotSetmealList);
//        本月就诊人数
        getBusinessReportDataParam.setThisMonthVisitsNumber(VisitsMonthend);
//        本月预约人数
        getBusinessReportDataParam.setThisMonthOrderNumber(bookingMonth);
//        本周就诊人数
        getBusinessReportDataParam.setThisWeekVisitsNumber(VisitsWeek);
//        本周预约人数
        getBusinessReportDataParam.setThisWeekOrderNumber(bookingWeek);
//        今日就诊人数
        getBusinessReportDataParam.setTodayVisitsNumber(VisitsTodays);
//        今日预约人数
        getBusinessReportDataParam.setTodayOrderNumber(bookingTodays);
//        本月会员数
        getBusinessReportDataParam.setThisMonthNewMember(Month);
//        本周会员数
        getBusinessReportDataParam.setThisWeekNewMember(Week);
//        全部会员数
        getBusinessReportDataParam.setTotalMember(alls);
//        今日会员数
        getBusinessReportDataParam.setTodayNewMember(Todays);
//        时间
        getBusinessReportDataParam.setReportDate(now);
        return getBusinessReportDataParam;
    }
    @Override
    public MemberReportVO getmember() {
        List<String> dateList = new ArrayList<>();
        LocalDate today = LocalDate.now();
        List<Integer> memberList = new ArrayList<>();
        for (int i = 11; i >= 0; i--) {
            LocalDate ld = today.minusMonths(i);
            String  date=ld.format(DateTimeFormatter.ofPattern("yyyy.MM"));
            dateList.add(date);
            int year = ld.getYear(); // 年
            int month = ld.getMonthValue(); // 月(1-12)
            LocalDate startDate = LocalDate.of(year,month,1);
            //本月最后一天 = 上个月 -1天
            LocalDate endDate = LocalDate.of(year,month,1).plusMonths(1).minusDays(1);;
            Integer member=memberDao.sumByYear(startDate,endDate);
            member=member==null?0:member;
            memberList.add(member);
        }
        MemberReportVO memberReportVO=new MemberReportVO();
        memberReportVO.setDateList(dateList);
        memberReportVO.setMemberList(memberList);
        return memberReportVO;
    }

    /**
     * 获取套餐统计数据(饼图)
     * @return
     */
    @Override
    public SetmealReportExcelVO getSetmealReport() {
        // 定义一个SetmealReportExcelVO类型的对象用来封装响应信息
        SetmealReportExcelVO setmealReportExcelVO = new SetmealReportExcelVO();
        // 创建一个字符串集合用来存储套餐名称
        List<String> setmealNames = new ArrayList<>();
        // 查询套餐名称和套餐预约数量
        List<SetmealCountVO> setmealCountVOList = orderDao.findSetmealReport();
        // 遍历查询到的套餐名称和套餐预约数量集合
        for (SetmealCountVO setmealCountVO : setmealCountVOList) {
            // 将套餐名称添加到套餐名称集合中
            setmealNames.add(setmealCountVO.getName());
        }
        // 将查询到的数据封装到VO中
        setmealReportExcelVO.setSetmealNames(setmealNames);
        setmealReportExcelVO.setSetmealCount(setmealCountVOList);
        return setmealReportExcelVO;
    }

    @Override
    public void exportBusiness(HttpServletResponse response) {
        try{

            //1: 读取模板
            InputStream in =this.getClass().getClassLoader().getResourceAsStream("report_template.xlsx");
            // 专门从 类路径下读取 资源文件
            // 流里面的字节变成 excel文件 ？
            XSSFWorkbook excel =new XSSFWorkbook(in);
            //2: 查询数据 写入模板
            //获取 第一个sheet
            XSSFSheet sheet =excel.getSheetAt(0);
            //3.1:得到时间
            LocalDate date = LocalDate.now();
            // 第三行 第六列  写入 开始时间至结束时间
            sheet.getRow(2).getCell(5).setCellValue(statis().getReportDate());
            // 第五行  第六列  第八列
            sheet.getRow(4).getCell(5).setCellValue(statis().getTodayNewMember());
            sheet.getRow(4).getCell(7).setCellValue(statis().getTotalMember());
            //第六行  第六列  第八列
            sheet.getRow(5).getCell(5).setCellValue(statis().getThisWeekNewMember());
            sheet.getRow(5).getCell(7).setCellValue(statis().getThisMonthNewMember());
            //第八行  第六列  第八列
            sheet.getRow(7).getCell(5).setCellValue(statis().getTodayOrderNumber());
            sheet.getRow(7).getCell(7).setCellValue(statis().getTodayVisitsNumber());
            //第九行  第六列  第八列
            sheet.getRow(8).getCell(5).setCellValue(statis().getThisWeekOrderNumber());
            sheet.getRow(8).getCell(7).setCellValue(statis().getThisWeekVisitsNumber());
            //第十行  第六列  第八列
            sheet.getRow(9).getCell(5).setCellValue(statis().getThisMonthOrderNumber());
            sheet.getRow(9).getCell(7).setCellValue(statis().getThisMonthVisitsNumber());
            //第十三行  第五列  第六列 第七列
            //第十四行  第五列  第六列 第七列
            //第十五行  第五列  第六列 第七列
            //第十六行  第五列  第六列 第七列
            int i = 12;
            for (HotSetmeal hotSetmeal : statis().getHotSetmeal()) {
                sheet.getRow(i).getCell(4).setCellValue(hotSetmeal.getName());
                sheet.getRow(i).getCell(5).setCellValue(hotSetmeal.getSetmeal_count());
                sheet.getRow(i).getCell(6).setCellValue(hotSetmeal.getProportion());
                i++;
            }

            //3: 导出模板
            // 通过response 对象获取字节输出流  通过excel方法写到浏览器上
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;fileName=" + statis().getReportDate() + "_report.xlsx");
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //释放资源
            out.flush();
            out.close();
            excel.close();
        }catch (Exception e){
            System.out.println("您读取模板有问题，它不是excel文件...");
            e.printStackTrace();
        }
    }
}
